package com.onpositive.simple.persistance;

import java.util.ArrayDeque;
import java.util.BitSet;

public class RAMStringStorage implements IStringStorage {
	
	
	protected BitSet deletedIdFlag ;
	protected ArrayDeque<Integer> vacantID ;
	protected int metricParams[] ;// metricParams[2*id] == offset( string(id) ), metricParams[2*id + 1] == length( string(id) ) ;
	
	protected StringBuilder container ;
	protected BitSet emptyCharFlag ;
	protected int stringsCount ; 
	
	
	public RAMStringStorage()
	{
		int initialCapacity = 12 ;
		
		emptyCharFlag = new BitSet() ;
		deletedIdFlag = new BitSet() ;
		container = new StringBuilder() ;		
		vacantID = new ArrayDeque<Integer>() ;
		metricParams = new int[initialCapacity] ;
		stringsCount = 0 ;
	}
	
	int getEmptyStringId(){ return 0 ; }
	
	@Override
	public int put(String s) {
		
		int id = getVacantId() ;
		
		deletedIdFlag.set( id, false ) ;
		
		int offset = container.length() ;
		int length = s.length() ;
		metricParams[ 2*id     ] = offset ;
		metricParams[ 2*id + 1 ] = length ;
		stringsCount++ ;
		
		container.append(s);	
		
		return id;
	}
	
	@Override
	public String get(int id) {
		
		int offset = metricParams[2*id  ] ;
		int length = metricParams[2*id+1] ;
		
		char buf[] = new char[length] ;
		container.getChars( offset, offset+length, buf, 0 );
		
		return new String( buf );
	}

	@Override
	public void delete(int id) {
		
		int start = metricParams[2*id  ] ;
		int end = start + metricParams[2*id+1] ;
		
		vacantID.add(id) ;
		for( int i = start ; i < end ; i++ )
			emptyCharFlag.set(i, true) ;
		
	}
	protected int getVacantId()
	{
		Integer id = vacantID.pollFirst() ;
		
		if( id == null ){
			
			if( metricParams.length < 2*( stringsCount+1 ) )
				reallocateParamsArray() ;
			
			id = stringsCount ;
		}
		return id ;		
	}
	
	protected void reallocateParamsArray()
	{
		int tmpParamsArray[] = new int[ (int)(metricParams.length * 1.4) ] ;
		for( int i = 0 ; i < metricParams.length ; i++  )
			tmpParamsArray[i] = metricParams[i] ;
		
		metricParams = tmpParamsArray ;		
	}
	
	protected void clearGarbage()
	{}

}
